<template>
    <div class="header">
        <div class="title">图片列表</div>
    </div>
    <div id="dropzone">
        <div class="pics">
            <div class="pic" :style="!pic.finish ? 'background-color: skyblue;' : 'background-color: #fff;'"
                v-for="(pic, index) in imgStore.imgMsg" :key="index" @click.self="toSort(pic, index)">
                <div class="checkbox"><input type="checkbox" v-model="pic.check" @click.self="" /></div>
                <img :src="pic.list[0]?.url" alt="">
                <span>{{ pic.title }}</span>
            </div>
        </div>
    </div>

    <!-- loading组件占位符 -->
    <div id="loadingComponent"></div>

</template>

<script setup>
import { ref, reactive, onMounted, onBeforeUnmount } from 'vue'
import { useRouter } from "vue-router";
import request from '../utils/request';
import useImgStore from "../store/img"
import lrz from 'lrz'; // 引入 lrz 库
let imgMsg = reactive([])

const PAGE_SIZE = 10; // 每页数据条数

onMounted(() => {
    // 判断本地缓存是否有图片数据
    const cachedImgMsg = imgStore.imgMsg

    if (cachedImgMsg.length > 0) {
        return
    } else {
        getImgMsg();
    }
});
let total = ref(0)
const getImgMsg = async () => {
    LoadingComponent.show();
    const res = await request.get(`/img?page=${imgStore.page}`);
    total.value = res.total
    LoadingComponent.hide();
    imgStore.imgMsg = res.data;
    imgStore.page++; // 增加页码，准备获取下一页数据
}

const getMoreImgMsg = async () => {
    // 如果已经获取的图片数量不是 PAGE_SIZE 的倍数，说明已经没有更多图片了
    if (imgStore.imgMsg.length >= total.value) {
        return;
    }
    LoadingComponent.show();
    const res = await request.get(`/img?page=${imgStore.page}`);
    LoadingComponent.hide();
    imgStore.imgMsg = imgStore.imgMsg.concat(res.data);
    imgStore.page++; // 增加页码，准备获取下一页数据
}

// 使用节流函数，确保滚动事件不会频繁触发
function throttle(func, limit) {
    let inThrottle;
    return function () {
        const args = arguments;
        const context = this;
        if (!inThrottle) {
            func.apply(context, args);
            inThrottle = true;
            setTimeout(() => inThrottle = false, limit);
        }
    };
}

// 通过节流包装 getMoreImgMsg 函数，间隔为 500ms
const throttledGetMoreImgMsg = throttle(getMoreImgMsg, 500);

// 监听滚动事件，应用节流（这里跳转到别的页面也会有这个东西，如果后续网页卡顿，再来处理）
window.addEventListener('scroll', () => {
    if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
        throttledGetMoreImgMsg();
    }
});
const imgStore = useImgStore()
const router = useRouter();
const toSort = (item, index) => {
    router.push({
        path: "/sort",
        query: {
            imgMsg: JSON.stringify(item),
            index: index
        }
    });
};
//跳转到历史记录页面
const toHistory = () => {
    router.push({
        path: "/history"
    })
}

//导入图片
let file = ref(null)
const tapFile = () => {
    file.value.click()
}
let fileAll = ref(null)
const tapFileAll = () => {
    fileAll.value.click()
}
let fileAdd = ref(null)

const tapFileAdd = ($event, index, pic) => {
    $event.stopPropagation();   //阻止冒泡
    pic.showDetail = false
    fileAdd.value[index].click()
}
//上传多个文件夹图片并压缩
const isDragOver = ref(false);

const handleDragOver = (event) => {
    isDragOver.value = true;
};

const handleDragLeave = (event) => {
    isDragOver.value = false;
};

const handleDrop = async (event) => {
    isDragOver.value = false;

    const items = event.dataTransfer.items;
    const folders = [];

    // 收集所有文件夹
    for (let i = 0; i < items.length; i++) {
        const item = items[i].webkitGetAsEntry();

        if (item.isDirectory) {
            folders.push(item);
        }
    }

    // 遍历每个文件夹进行处理
    for (let i = 0; i < folders.length; i++) {
        const folder = folders[i];
        const directoryReader = folder.createReader();
        const entries = await readEntries(directoryReader);
        const files = entries.filter(entry => entry.isFile);

        if (files.length === 0) {
            continue; // 跳过空文件夹
        }

        // 准备上传文件
        const newImgMsg = {
            id: imgStore.imgMsg.length + 1,
            list: [],
            title: `第${imgStore.imgMsg.length + 1}组`,
            finish: false,
            check: false,
            showDetail: false
        };

        // 处理每个文件
        for (let j = 0; j < files.length; j++) {
            const fileEntry = files[j];
            try {
                const file = await getFileFromEntry(fileEntry);

                // 检查文件是否是图片
                if (!file.type.startsWith('image/')) {
                    continue;
                }

                // 压缩图片
                const compressedFile = await lrz(file, {
                    quality: 0.7,
                    width: 800,
                    height: 600
                });

                const data = {
                    id: j + 1,
                    url: compressedFile.base64,
                    name: file.name
                };

                newImgMsg.list.push(data);
            } catch (error) {
                console.error('处理文件时出错:', error);
            }
        }

        // 模拟上传请求
        setTimeout(async () => {
            try {
                const res = await request.post("/img", newImgMsg);
                LoadingComponent.hide();

            } catch (error) {
                console.error('上传失败:', error);
            }
        }, 200);

        // 将新图片消息添加到状态管理器
        imgStore.imgMsg.push(newImgMsg);
    }
    //重置页面
    // console.log(imgStore.imgMsg);
    // imgStore.imgMsg = []
    // imgStore.page = 1
    // getImgMsg()

};

// 辅助函数：从文件 entry 中获取文件对象
const getFileFromEntry = async (fileEntry) => {
    return new Promise((resolve, reject) => {
        fileEntry.file((file) => {
            resolve(file);
        }, reject);
    });
};
// 辅助函数：递归读取文件夹中的文件
const readEntries = async (directoryReader) => {
    return new Promise((resolve, reject) => {
        directoryReader.readEntries((entries) => {
            resolve(entries);
        }, reject);
    });
};

// import FilePondPluginFileEncode from 'filepond-plugin-file-encode';
// import 'filepond/dist/filepond.css';
// import 'filepond-plugin-file-encode/dist/filepond-plugin-file-encode.css';
// import { FilePond, registerPlugin } from 'filepond';
// const filepondInput = ref(null);
// // 在组件加载完成后初始化 FilePond
// const initializeFilePond = () => {
//       registerPlugin(FilePondPluginFileEncode);

//       const pond = FilePond.create(filepondInput.value, {
//         allowMultiple: true,
//         allowDirectories: true,
//         allowFileEncode: true
//       });
//     };
// const addPidMultiple = async () =>{

// }
// 上传图片并压缩
const addPic = async (e) => {
    LoadingComponent.show();

    let files = e.target.files;
    let newImgMsg = {
        id: imgStore.imgMsg.length + 1,
        list: [],
        title: `第${imgStore.imgMsg.length + 1}组`,
        finish: false,
        check: false,
        showDetail: false
    };

    for (let i = 0; i < files.length; i++) {
        let file = files[i];

        // 检查文件是否是图片
        if (!file.type.startsWith('image/')) {
            continue;
        }

        // 压缩图片
        try {

            // 使用 lrz 进行压缩
            const compressedFile = await lrz(file, {
                quality: 0.7, // 压缩质量，0.7 是默认值，可以根据需要调整
                width: 800,   // 最大宽度，可以根据需要调整
                height: 600    // 最大高度，可以根据需要调整
            });


            let data = {
                id: i + 1,
                url: compressedFile.base64, // 获取压缩后的图片 base64 编码
                name: file.name
            };

            newImgMsg.list.push(data);
        } catch (error) {
        }
    }

    // 模拟上传请求
    setTimeout(async () => {
        try {
            const res = await request.post("/img", newImgMsg);
            LoadingComponent.hide();
        } catch (error) {
        }
    }, 200);

    // 将新图片消息添加到状态管理器
    imgStore.imgMsg.push(newImgMsg);
};
// 后续添加图片
const addImg = async (e, pic) => {
    let files = e.target.files;
    let list = pic.list

    for (let i = 0; i < files.length; i++) {
        let file = files[i];

        // 检查文件是否是图片
        if (!file.type.startsWith('image/')) {
            continue;
        }

        // 压缩图片
        try {

            // 使用 lrz 进行压缩
            const compressedFile = await lrz(file, {
                quality: 0.7, // 压缩质量，0.7 是默认值，可以根据需要调整
                width: 800,   // 最大宽度，可以根据需要调整
                height: 600    // 最大高度，可以根据需要调整
            });


            let data = {
                id: list.length + 1,
                url: compressedFile.base64, // 获取压缩后的图片 base64 编码
                name: file.name
            };

            list.push(data);
        } catch (error) {
        }
    }

    // 模拟上传请求
    setTimeout(async () => {
        try {
            LoadingComponent.show();
            const res = await request.put("/img", { _id: pic._id, list: list });
            LoadingComponent.hide();
        } catch (error) {
        }
    }, 200);

    // 将新图片消息添加到状态管理器
    // imgStore.imgMsg.push(newImgMsg);
};
//导出为excel表
import { exportJsonToExcel } from '../utils/Export2Excel.js'
const derive = () => {

    let checkList = imgStore.imgMsg.filter(i => {
        return i.check == true
    })
    //分批下载功能
    // if (checkList.length > 0) {
    //     let a = Math.ceil(checkList.length / 10)
    //     for (let i = 0; i <= a; i++) {
    //         let checkListCopy = JSON.parse(JSON.stringify(checkList))
    //         let part = checkListCopy.splice(i * 10, 10)
    //         setTimeout(() => {
    //             if (part.length > 0) {

    //                 part.forEach(item => {
    //                     const data = reactive({
    //                         arr: item.list
    //                     })
    //                     let data2 = []
    //                     for (const key in data.arr) {
    //                         let data1 = []//设置一个二级列表，导出的表格每一行为一个二级列表
    //                         data1.push(data.arr[key].id, data.arr[key].name)//循环把接口中需要用到的数据加入二级列表

    //                         data2.push(data1)//把二级列表塞入一级列表
    //                     }

    //                     exportJsonToExcel({
    //                         // 这里用到了Export2Excel.js
    //                         header: ["序号", "图片文件名"],//表名个数可以不等于数据每一行的列数
    //                         data: data2,//把data2传递给数据表，或者不用data2，用自己设置的数据来代替
    //                         //如：[[1,1,1],[2,2,2],[3,3,3]] 就是导出三行，以此类推
    //                         name: item.title//文件名
    //                     })

    //                 });
    //             }
    //         }, i * 2000);
    //     }

    // } else {
    //     return
    // }
    //正常下载（不分批）
    if (checkList.length > 0) {
        checkList.forEach(item => {
            const data = reactive({
                arr: item.list
            })
            let data2 = []
            for (const key in data.arr) {
                let data1 = []//设置一个二级列表，导出的表格每一行为一个二级列表
                data1.push(data.arr[key].id, data.arr[key].name)//循环把接口中需要用到的数据加入二级列表

                data2.push(data1)//把二级列表塞入一级列表
            }
            exportJsonToExcel({
                // 这里用到了Export2Excel.js
                header: ["序号", "图片文件名"],//表名个数可以不等于数据每一行的列数
                data: data2,//把data2传递给数据表，或者不用data2，用自己设置的数据来代替
                //如：[[1,1,1],[2,2,2],[3,3,3]] 就是导出三行，以此类推
                name: item.title//文件名
            })
        });
    } else {
        return
    }
}

//详情模块
const toggle = ($event, pic) => {
    //阻止冒泡
    $event.stopPropagation();
    if (pic.showDetail) {
        pic.showDetail = false
    } else {
        pic.showDetail = true
    }
}
//查看某组历史记录功能
const showHistory = ($event, pic) => {
    $event.stopPropagation();
    pic.showDetail = false
    router.push({
        path: "/history",
        query: {
            imgname: pic.title
        }
    })

}
//删除某组图片
const deleteImg = async ($event, pic) => {
    $event.stopPropagation();
    pic.showDetail = false
    LoadingComponent.show();
    const res = await request.delete(`/img/${pic._id}`)
    LoadingComponent.hide();
    total.value--
    imgStore.imgMsg.forEach((item, index) => {
        if (item._id == pic._id) {

            imgStore.imgMsg.splice(index, 1)
        }
    })

}

//修改组名
let showMask = ref(false)
let changeId = ref(null)
let imgname = ref('')
let err = ref(false)
const putName = ($event, pic) => {
    $event.stopPropagation();
    pic.showDetail = false
    showMask.value = true
    changeId.value = pic._id
}
const submit = async () => {
    if (imgname.value.trim() == "") {
        err.value = true
        return
    }
    let updateData = {
        title: imgname.value
    }
    LoadingComponent.show();
    const res = await request.put("/img", { _id: changeId.value, ...updateData });
    LoadingComponent.hide();
    imgname.value = ''
    err.value = false
    //重置页面
    imgStore.page = 1
    getImgMsg()
    showMask.value = false
}
// 定义一个loading组件对象
const LoadingComponent = {
    show() {
        // 创建loading覆盖层的DOM结构
        const loadingOverlay = document.createElement('div');
        loadingOverlay.id = 'loadingOverlay';
        loadingOverlay.className = 'loading-overlay';

        // 创建loading spinner的DOM结构
        const spinner = document.createElement('div');
        spinner.className = 'loading-spinner';

        // 将spinner添加到overlay中
        loadingOverlay.appendChild(spinner);

        // 将loading覆盖层添加到页面中
        const container = document.getElementById('loadingComponent');
        container.appendChild(loadingOverlay);
    },

    hide() {
        // 移除loading覆盖层
        const overlay = document.getElementById('loadingOverlay');
        if (overlay) {
            overlay.parentNode.removeChild(overlay);
        }
    }
};

</script>
<style scoped lang="less">
#dropzone {
    padding: 20px;
    text-align: center;
}

.header {
    width: 100%;
    height: 10vh;
    text-align: center;
    position: relative;
    background: skyblue;
    color: #fff;

    .left {
        position: fixed;
        bottom: 0;
        right: 1vw;
        transform: translateY(-50%);
        display: flex;
        z-index: 9999;

        .add {
            width: 6vw;
            height: 6vw;
            background-color: skyblue;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 1.2rem;
            transition: all .3s;
            color: #fff;
            margin-left: 2vw;
            border: 1px solid #fff;

            &:hover {
                cursor: pointer;
            }

            input {
                display: none;
            }
        }
    }

    .title {
        font-size: 2rem;
        line-height: 10vh;
    }

    .right {
        position: absolute;
        top: 50%;
        right: 1vw;
        transform: translateY(-50%);
        display: flex;
        padding: 1vw;
        font-size: 1rem;
        margin-left: 1vw;
        background-color: #fff;
        color: #000;
        transition: all .3s;

        &:hover {
            cursor: pointer;
            transform: translateY(-50%) translateX(-2px);
        }
    }
}

.pics {
    width: 100%;
    min-height: 80vh;
    padding-bottom: 30vh;
    display: flex;
    flex-wrap: wrap;
    align-items: start;
    justify-content: start;


    .pic {
        position: relative;
        box-sizing: border-box;
        width: 15%;
        display: flex;
        flex-direction: column;
        align-items: center;
        transition: all .3s;
        justify-content: space-evenly;
        padding: 2vw;
        margin: 1vw 2vw;
        box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);

        .checkbox {
            position: absolute;
            top: .5vw;
            left: .5vw;
            width: 2vw;
            height: 2vw;

            input {
                width: 100%;
                height: 100%;
            }
        }

        img {
            margin-top: 2vw;
            width: 100%;
            height: 10vw;
        }

        span {
            margin-top: 1vw;
            font-size: 1rem;
        }

        .toggle {
            user-select: none;
            position: absolute;
            top: .5vw;
            right: .5vw;
            background-color: skyblue;
            color: #fff;
            padding: .5vw;

            &:hover {
                cursor: pointer;
                transition: all .2s;
                background-color: rgb(142, 219, 250);
            }
        }

        .detail_show {
            transition: all .3s;
            position: absolute;
            top: 0;
            right: 0;
            opacity: 1;
            transform: translateX(100%);
            width: 100%;
            height: 100%;
            background-color: #fff;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: start;
            border-left: 1px solid #f1f1f1;
            z-index: 9999;

            div {
                width: 100%;
                padding: 1vw 0;
                text-align: center;
                border-bottom: 1px solid #f1f1f1;

                &:hover {
                    cursor: pointer;
                    background-color: #f3f3f3;
                }

            }

        }

        .detail_hide {
            position: absolute;
            top: 0;
            left: 0;
            opacity: 0;
            z-index: -1;
        }

        &:hover {
            cursor: pointer;
            box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
        }
    }
}

.derive {
    position: fixed;
    bottom: 9vw;
    right: 5vw;
    width: 6vw;
    height: 6vw;
    background-color: skyblue;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.2rem;
    transition: all .3s;
    color: #fff;
    border: 1px solid #fff;

    &:hover {
        cursor: pointer;
    }
}

.mask {
    z-index: 999;
    width: 100%;
    height: 100vh;
    position: fixed;
    top: 0;
    left: 0;
    background: rgba(0, 0, 0, 0.5);
    display: flex;
    justify-content: center;
    align-items: center;

    .dialog {
        width: 25%;
        background-color: #fff;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        border-radius: 7px;
        overflow: hidden;

        .header {
            width: 100%;
            background-color: skyblue;
            font-size: 25px;
            font-weight: 700;
            text-align: center;
            color: #fff;
            line-height: 4vw;
        }

        .body {
            width: 100%;
            padding: 1vw 2vw 0;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;

            .msg {
                font-size: 20px;
                margin: 10px 0;
            }

            input {
                width: 80%;
                height: 30px;
                margin: 1vw 0;
                border-radius: 7px;
                transition: all .6s;
                border: 0;

                &:focus {
                    outline: none;
                }
            }

            .err {
                border: 1px solid red !important;
                animation: identifier 2s;

                @keyframes identifier {
                    0% {
                        transform: translateX(0);
                    }

                    15% {
                        transform: translateX(-5px);
                    }

                    20% {
                        transform: translateX(5px);
                    }

                    25% {
                        transform: translateX(-5px);
                    }

                    30% {
                        transform: translateX(5px);
                    }

                    35% {
                        transform: translateX(-5px);
                    }

                    40% {
                        transform: translateX(5px);
                    }

                    45% {
                        transform: translateX(-5px);
                    }

                    50% {
                        transform: translateX(0);
                    }

                    100% {
                        transform: translateX(0);
                    }

                }
            }

            .default {
                border: 1px solid #ccc !important;
            }

            .buts {
                width: 100%;
                display: flex;
                align-items: center;
                justify-content: space-between;

                .button {
                    width: 50%;
                    height: 3vw;
                    background-color: #409eff;
                    color: #fff;
                    text-align: center;
                    line-height: 3vw;
                    cursor: pointer;
                    font-size: 20px;
                    margin-top: 1vw;

                    &:first-child {
                        border-right: 1px solid skyblue;
                    }
                }
            }
        }
    }
}
</style>